{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MeanHamilMinimizer_rigetti_autograd\n",
    "\n",
    "* Feedback loop between Qubiter and Rigetti QVM\n",
    "* minimization via autograd\n",
    "\n",
    ">This notebook calls Rigetti's method QVMConnection() which only works if you first:\n",
    "* install the Rigetti Forest SDK available at https://www.rigetti.com/forest\n",
    "* open a second terminal (besides the one that runs this notebook) and type \"qvm -S\" in it\n",
    "* open a third terminal and type \"quilc -S\" in it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/rrtucci/PycharmProjects/qubiter/qubiter/jupyter_notebooks\n",
      "/home/rrtucci/PycharmProjects/qubiter\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "print(os.getcwd())\n",
    "os.chdir('../../')\n",
    "print(os.getcwd())\n",
    "sys.path.insert(0,os.getcwd())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "np installed? False\n",
      "numpy installed? True\n",
      "autograd.numpy installed? True\n",
      "loaded OneQubitGate, WITH autograd.numpy\n",
      "pu2 in dir True\n",
      "pu2 in sys.modules False\n"
     ]
    }
   ],
   "source": [
    "import qubiter.adv_applications.setup_autograd # do this first!\n",
    "from qubiter.adv_applications.MeanHamil_native import *\n",
    "from qubiter.adv_applications.MeanHamil_rigetti import *\n",
    "from qubiter.adv_applications.MeanHamilMinimizer import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyquil.quil import Program\n",
    "from pyquil.api import QVMConnection\n",
    "from pyquil.gates import *\n",
    "from pyquil import get_qc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "qvm_url = \"http://localhost:5000\"\n",
    "compiler_server_address = \"tcp://localhost:5555\"\n",
    "forest_url = \"https://forest-server.qcs.rigetti.com\"\n",
    "qvm = QVMConnection(endpoint=qvm_url, compiler_endpoint=compiler_server_address)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## First Example (taken from Pennylane docs). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "qc = get_qc('2q-qvm')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_qbits = 2\n",
    "file_prefix = 'mean_hamil_rigetti_test1'\n",
    "emb = CktEmbedder(num_qbits, num_qbits)\n",
    "wr = SEO_writer(file_prefix, emb)\n",
    "wr.write_Rx(0, rads='#1')\n",
    "wr.write_Ry(0, rads='#2')\n",
    "wr.close_files()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>ROTX\t#1\tAT\t0</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>ROTY\t#2\tAT\t0</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_eng_file(jup=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>|   Rx</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>|   Ry</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_pic_file(jup=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "fun_name_to_fun = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hamil=\n",
      " 1.0 [Z0]\n"
     ]
    }
   ],
   "source": [
    "hamil = QubitOperator('Z0', 1.)\n",
    "print('hamil=\\n', hamil)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "init_var_num_to_rads = {1: .3, 2: .8}\n",
    "all_var_nums = [1, 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_samples = 100\n",
    "print_hiatus = 1\n",
    "verbose = False\n",
    "np.random.seed(1234)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "emp_mhamil = MeanHamil_rigetti(qc, file_prefix, num_qbits, hamil,\n",
    "            all_var_nums, fun_name_to_fun, num_samples=num_samples)\n",
    "targ_mhamil = MeanHamil_native(file_prefix, num_qbits, hamil,\n",
    "            all_var_nums, fun_name_to_fun, simulator_name='SEO_simulator') # zero samples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "mini = MeanHamilMinimizer(emp_mhamil, targ_mhamil,\n",
    "                 all_var_nums, init_var_num_to_rads,\n",
    "                 print_hiatus=print_hiatus, verbose=verbose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "pg += RX(rads1*(-2), 0)\n",
      "pg += RY(rads2*(-2), 0)\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "emp_mhamil.translator.print_aqasm_file()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PRAGMA INITIAL_REWIRING \"PARTIAL\"\n",
      "RESET\n",
      "DECLARE ro BIT[2]\n",
      "DECLARE rads1 REAL[1]\n",
      "DECLARE rads2 REAL[1]\n",
      "RX(rads1*-2) 0\n",
      "RY(rads2*-2) 0\n",
      "MEASURE 0 ro[0]\n",
      "MEASURE 1 ro[1]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(emp_mhamil.pg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x_val~ (#1, #2)\n",
      "iter=0, cost=-0.060000, targ_cost=-0.024099, x_val=0.300000, 0.800000\n",
      "iter=1, cost=-0.340000, targ_cost=-0.292577, x_val=0.296703, 0.965738\n",
      "iter=2, cost=-0.620000, targ_cost=-0.551784, x_val=0.257234, 1.128646\n",
      "iter=3, cost=-0.680000, targ_cost=-0.764436, x_val=0.194856, 1.271741\n",
      "iter=4, cost=-0.880000, targ_cost=-0.896213, x_val=0.132062, 1.380452\n",
      "iter=5, cost=-0.960000, targ_cost=-0.959154, x_val=0.083588, 1.453728\n",
      "iter=6, cost=-1.000000, targ_cost=-0.984771, x_val=0.051216, 1.499885\n",
      "iter=7, cost=-1.000000, targ_cost=-0.994446, x_val=0.030971, 1.528101\n",
      "iter=8, cost=-1.000000, targ_cost=-0.997991, x_val=0.018635, 1.545146\n",
      "iter=9, cost=-1.000000, targ_cost=-0.999275, x_val=0.011193, 1.555399\n"
     ]
    }
   ],
   "source": [
    "mini.find_min(minlib='autograd', num_iter=10, descent_rate=.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Second, more complicated example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "qc = get_qc('4q-qvm')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_qbits = 4\n",
    "file_prefix = 'mean_hamil_rigetti_test2'\n",
    "emb = CktEmbedder(num_qbits, num_qbits)\n",
    "wr = SEO_writer(file_prefix, emb)\n",
    "wr.write_Ry(2, rads=np.pi/7)\n",
    "wr.write_Rx(1, rads='#2*.5')\n",
    "wr.write_Ry(1, rads='-#1*.3')\n",
    "wr.write_cnot(2, 3)\n",
    "wr.write_qbit_swap(1, 2)\n",
    "wr.close_files()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>ROTY\t25.714286\tAT\t2</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>ROTX\t#2*.5\tAT\t1</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>ROTY\t-#1*.3\tAT\t1</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>SIGX\tAT\t3\tIF\t2T</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>SWAP\t2\t1</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_eng_file(jup=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style='font-family:monospace'><tr><td style='border-right:1px solid red;'>1</td><td style='text-align:left;'><pre>|   Ry  |   |</pre></td></tr><td style='border-right:1px solid red;'>2</td><td style='text-align:left;'><pre>|   |   Rx  |</pre></td></tr><td style='border-right:1px solid red;'>3</td><td style='text-align:left;'><pre>|   |   Ry  |</pre></td></tr><td style='border-right:1px solid red;'>4</td><td style='text-align:left;'><pre>X---@   |   |</pre></td></tr><td style='border-right:1px solid red;'>5</td><td style='text-align:left;'><pre>|   <--->   |</pre></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "wr.print_pic_file(jup=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "fun_name_to_fun = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hamil=\n",
      " 0.7 [X1 Y2] +\n",
      "0.4 [Y1 X2 Y3]\n"
     ]
    }
   ],
   "source": [
    "hamil = QubitOperator('X1 Y3 X1 Y1 X2', .4) + QubitOperator('Y2 X1', .7)\n",
    "print('hamil=\\n', hamil)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "init_var_num_to_rads = {1: 2.1, 2: 3.4}\n",
    "all_var_nums = [1, 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_samples = 100\n",
    "print_hiatus = 1\n",
    "verbose = False\n",
    "np.random.seed(1234)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "emp_mhamil = MeanHamil_rigetti(qc, file_prefix, num_qbits, hamil,\n",
    "            all_var_nums, fun_name_to_fun, num_samples=num_samples)\n",
    "targ_mhamil = MeanHamil_native(file_prefix, num_qbits, hamil,\n",
    "            all_var_nums, fun_name_to_fun, simulator_name='SEO_simulator') # zero samples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "mini = MeanHamilMinimizer(emp_mhamil, targ_mhamil,\n",
    "                 all_var_nums, init_var_num_to_rads,\n",
    "                 print_hiatus=print_hiatus, verbose=verbose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "pg += RY(-0.8975979109989651, 2)\n",
      "pg += RX(rads2*.5*(-2), 1)\n",
      "pg += RY(-rads1*.3*(-2), 1)\n",
      "pg += CNOT(2, 3)\n",
      "pg += SWAP(2, 1)\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "emp_mhamil.translator.print_aqasm_file()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PRAGMA INITIAL_REWIRING \"PARTIAL\"\n",
      "RESET\n",
      "DECLARE ro BIT[4]\n",
      "DECLARE rads1 REAL[1]\n",
      "DECLARE rads2 REAL[1]\n",
      "RY(-0.8975979109989651) 2\n",
      "RX(rads2*0.5*-2) 1\n",
      "RY(-1*rads1*0.3*-2) 1\n",
      "CNOT 2 3\n",
      "SWAP 2 1\n",
      "RY(-pi/2) 1\n",
      "RX(pi/2) 2\n",
      "MEASURE 0 ro[0]\n",
      "MEASURE 1 ro[1]\n",
      "MEASURE 2 ro[2]\n",
      "MEASURE 3 ro[3]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(emp_mhamil.pg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x_val~ (#1, #2)\n",
      "iter=0, cost=-0.336000, targ_cost=-0.287864, x_val=2.100000, 3.400000\n",
      "iter=1, cost=-0.316000, targ_cost=-0.288742, x_val=2.105548, 3.392383\n",
      "iter=2, cost=-0.370000, targ_cost=-0.289583, x_val=2.111049, 3.384978\n",
      "iter=3, cost=-0.192000, targ_cost=-0.290390, x_val=2.116503, 3.377780\n",
      "iter=4, cost=-0.246000, targ_cost=-0.291163, x_val=2.121910, 3.370784\n",
      "iter=5, cost=-0.310000, targ_cost=-0.291904, x_val=2.127269, 3.363985\n",
      "iter=6, cost=-0.224000, targ_cost=-0.292615, x_val=2.132580, 3.357378\n",
      "iter=7, cost=-0.426000, targ_cost=-0.293297, x_val=2.137843, 3.350958\n",
      "iter=8, cost=-0.170000, targ_cost=-0.293951, x_val=2.143058, 3.344720\n",
      "iter=9, cost=-0.274000, targ_cost=-0.294578, x_val=2.148225, 3.338660\n"
     ]
    }
   ],
   "source": [
    "mini.find_min(minlib='autograd', num_iter=10, descent_rate=.1)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "colors": {
    "hover_highlight": "#DAA520",
    "running_highlight": "#FF0000",
    "selected_highlight": "#FFD700"
   },
   "moveMenuLeft": true,
   "nav_menu": {
    "height": "12px",
    "width": "252px"
   },
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "threshold": 4,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false,
   "widenNotebook": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
